--
-- Author:      name
-- DateTime:    2018-05-28 15:57:48
-- Description: 游戏主逻辑

local skynet = require "skynet"
local log = require "Log"
local config = require "configquery"
local Timer = require "timer"
local FSM = require "fsm"
local NodeMessage = require "NodeMessage"
local json = require "cjson"
require "common"
local Event = require "paohuzi.Event"
local EventQueue = require "paohuzi.EventQueue"
local Player = require "paohuzi.Player"

local mix_array = mix_array
local table_clone = table_clone
local floor = math.floor
local four_five = math.four_five
local random = math.random

local MachineBase = require "common.MachineBase"
local Machine = class("Machine",MachineBase)

function Machine:ctor(tableid,rule)
	json.encode_sparse_array(true)
	self.super:ctor(tableid,rule) --父类

	self.tbSeatRes = {} --座位结果
	self.winnerSeat = nil --赢家座位
	self.tbSeatCard = {} --座位上的原始牌

	self.operSeatid = nil --当前操作的座位
	self.startSeatid = nil --开始操作的座位id
	self.firstCard = 0 --庄多的一张牌
	self.curDealSeatid = nil --当前出牌的玩座位id
	self.curGetCard = nil --当前摸的牌
	self.curDealCard = nil --当前出的牌
	self.tbPlayers = {}
	self.eventQueue = EventQueue.new()

	self.HU = 4
	self.PAO = 3
	self.PENG = 2
	self.CHI = 1	

	-- {"play_type":12,"game_num":0,"cost_type":3,"cap_num":200,"clubid":0}
	--房卡配置
	-- local data = self.nodeMessage:callService('dbmgr_service','reload_private_tables',tableid)
	local sql = string.format("select * from private_tables where tableid = %d", tableid)
	local data = skynet.call("mysql_service", "lua", "execute", sql)	
	data = data[1]	
	if not next(data) then 
		print("__房间不存在_data___",data,tableid)
	end
	local setting = json.decode(data.setting)
	self.config = {}
	self.config.play_type = setting.play_type --玩法类型
	self.config.play_count = setting.play_count or 100--最大局数
	if self.config.play_type == 12 then 
		self.config.play_count = 0
	end
	self.config.pay_type = setting.cost_type or 1--支付类型
	self.config.verify_code = data.number or 1--房号
	self.config.owner = data.managerid --房主id
	self.config.vote_time = 120 --投票时间
	self.config.cost = setting.cost or 0--花费
	self.config.player_num = setting.player_num or 3 --人数
	self.config.bottomNum = 1	--底分
	self.config.clubid = setting.clubid or 0 --俱乐部id
	self.config.cap_num = setting.cap_num --封顶胡息
	if self.config.pay_type==2 then --aa付
		self.config.cost = math.floor(self.config.cost/self.config.player_num)
	end
	--解散桌子	
	self.handlerVoteTime = nil --解散桌子定时器
	self.sourceid = nil --发起者id
	self.voteTime = 120 --投票时间
	self.tbCloseVote = {} --请求解散桌子
	self.closeVoteTime = 90 --投票解散桌子时间
	
	self.manager = nil
	self.managerid = self.config.owner --房主id
	self.tableNum = self.config.verify_code --房号
	self.fangkaEnd = false --桌子已结束
	self.room_flag = ""..self.tableid..os.time()--大局唯一标识
	self.tbWinNum = {0,0,0} --赢的次数
	self.cost = self.config.cost
	self.bGameStart = false
	self.maxJuShu = self.config.play_count --最大局数
	self.endData = nil --结算数据
	self.bWeiHu = false	--偎胡标记
	self.tbJW = {} --座位对应的经纬度
-----------------------

	self.winnerSeatId = nil --赢家座位
	self.winChip = 0 --玩家赢的筹码
	self.waitTime = 0 --桌子等待开始的时间 
	self.curJuShu = 0 --第几局
	self.maxWaitTime = 60*30 --桌子等待开始的时间 

	self.curRound = 1 --当前操作轮数
	self.tbCardRecord = {
		game_start={}, --游戏开始时玩家信息
		game_end={}, --游戏结束时玩家信息
		game_oper={}, --游戏操作过程
		game_config={}, --游戏设置
	} --牌局记录表
	--操作1吃，2碰，3偎，4提，5跑，6胡，7出牌，8摸牌
	self.operList = {		
		chi =1,		--吃			
		peng = 2, 	--碰
		wei = 3,
		ti = 4,
		pao = 5,	--跑		
		hu = 6,		--胡
		deal = 7,		--出牌
		mopai = 8,
	}	
	self.playerState = {		
		playing = 1, --正常
		auto = 2,	 --托管		
		ready = 3,   --已准备
		disconnect = 4, --离线		
	}	
	--状态时间
	self.statusTime = {
		wait = 1,		--等待时间
		rest = 1,		--休息时间
		start = 3,		--开始
		first = 3,		--第一张牌
		oper = 10,		--操作时间	
		deal = 5,		--出牌
		mopai = 5,		--摸牌
		settlement = 1, --结算时间
	}
	self.tiWeiPaoState = false --提偎跑是可胡状态
	--state1 --eventName --state2 --callback
	self.gameStateTransitionTable = {
		{"rest", 		"to_start", 			"start", 		function() self:onStart() end },
		{"start", 		"to_first",				"first", 		function() self:onFirst() end },			
		{"first", 		"to_deal",				"deal", 		function() self:onDeal() end },
		{"first", 		"first_to_oper",		"oper", 		function() self:onOper() end },		
		{"deal", 		"to_oper",				"oper", 		function() self:onOper() end },		
		{"mopai", 		"to_oper",				"oper", 		function() self:onOper() end },
		{"oper", 		"to_deal",				"deal", 		function() self:onDeal() end },	
		{"deal", 		"deal_to_mopai",		"mopai", 		function() self:onMopai() end },			
		{"oper", 		"to_mopai",				"mopai", 		function() self:onMopai() end },
		{"oper", 		"to_settlement",		"settlement", 	function() self:onSettlement() end },
		{"mopai", 		"to_settlement",		"settlement", 	function() self:onSettlement() end },
		{"settlement", 	"to_rest", 				"rest", 		function() self:onRest() end},
		{"rest", 		"to_wait", 				"wait", 		function() self:onWait() end},		
		{"wait", 		"to_rest", 				"rest", 		function() self:onRest() end},

		{"oper", 		"to_tipaoweihu",		"tipaoweihu", 	function() self:onTiPaoWeiHu() end },		
		{"tipaoweihu", 	"to_deal",				"deal", 		function() self:onDeal() end },
		{"tipaoweihu", 	"to_mopai",				"mopai", 		function() self:onMopai() end },		
		{"tipaoweihu", 	"to_settlement",		"settlement", 	function() self:onSettlement() end },
	
	}
	--游戏逻辑状态机
	self.fsm = FSM.new(self.gameStateTransitionTable)	

	local tbStateTransitoin = {
		{"rest", 		"to_start", 			"start", 		function() self:onStartVote() end },
		{"start", 		"to_end", 				"end", 			function() self:onEndVote() end },
		{"start", 		"to_rest", 				"rest", 		function() self:onRestVote() end },
	}
	--投票状态机
	self.fsm2 = FSM.new(tbStateTransitoin)
	self.fsm2:set("rest")		
	self:reset()
	-- self:getCard()
end

---------------------------------------------------------
-- private
---------------------------------------------------------
--重置数据
function Machine:reset()
	self.operStartTime = 0

	self.winnerSeatId = nil --赢家座位
	self.winChip = 0 --玩家赢的筹码
	self.operSeatid = nil


	-- self.startSeatid = nil
	self.firstCard = 0 --庄多的一张牌
	self.curDealSeatid = nil --当前出牌的玩座位id
	self.curGetCard = nil --当前摸的牌
	self.curDealCard = nil --当前出的牌
	self.bGameStart = false --开始标记
	self.curRound = 1
	self.tiWeiPaoState = false --提偎跑是可胡状态
	self.endData = nil --结算数据
	self.bWeiHu = false	--偎胡标记
-------------------
	self.tbCardRecord = {
		game_start={}, --游戏开始时玩家信息
		game_end={}, --游戏结束时玩家信息
		game_oper={}, --游戏操作过程
		game_config={}, --游戏设置
	} --牌局记录表
	--玩家自身状态
	for k,v in pairs(self.player_list) do 
		v.playing = false			
		v.oper = nil
		v.look = nil
		v.auto = nil
	end
end


--玩家状态值 
function Machine:getPlayerState(player)
	local state = 0 	
	if player.ready then 
		state = self.playerState.ready
	end	
	if player.playing then
		state = self.playerState.playing
	end
	if player.auto then
		state = self.playerState.auto
	end		
	if player.disconnect then
		state = self.playerState.disconnect
	end			
	return state
end

--@override
function Machine:sitDownCallback( playerid )
	log.debug("__1111111111___sitDownCallback_______")
	local player = self:getPlayer(playerid)
	local seatPlayer = self:getCharacter(player)
	seatPlayer.state = self:getPlayerState(player)
	local data = {phz_nt_seat_change = {
		tableid = self.tableid,
		seatid = player.seatid,
		seat_player = seatPlayer,
		playerid = playerid,
		leave = false,
	}}	
	self:sendToOther(playerid,data)
end

function Machine:sitUpCallback(seatid,playerid)	
	local data = {phz_nt_seat_change = {
		tableid = self.tableid,
		seatid = seatid,
		playerid = playerid,
		leave = true,
	}}
	log.debug("_____situp___",data)	
	self:sendToAll(data)
	self.player_list[playerid] = nil
end

--加入玩家
function Machine:canJoin(playerid)
	print("______________Machine:canJoin", playerid)
	local num = 0 
	for k,v in pairs(self.player_list) do 
		if k ~= self.managerid then 
			num = num + 1
		end
	end
	if num >= 2 and playerid ~= self.managerid then 
		return false
	end
	return true
end

--加入玩家
function Machine:addPlayer(player)
	print("______________Machine:addPlayer", player)
	self:readUserInfo(player)
	if self.managerid == player.playerid then 
		self.manager = table.copy(player)
	end
	player.chip = 0
	self.player_list[player.playerid] = player
	self:updatePlayerNum()
end

--离线清除
function Machine:removePlayer()
	for k,v in pairs(self.player_list) do 	
		if v.disconnect and not v.ready and k~=self.managerid and self.curJushu==0 then 				
			--设置玩家所在桌子id为0	
			self:sendGate(v, 'update_tableid', 0)
			self:sitUp(k)
			self.player_list[k] = nil
			self:updatePlayerNum()
			print("踢走掉线 o#######",k,v.disconnect,v.chip,self.minChip)
		end
	end
end


--删除桌子
function Machine:deleteTable(playerid)
	local data = {nt_manager_close={
		playerid=playerid,
		tableid=self.tableid,
	}}
	self:sendToAll(data)
	print("_______closePrivate___",data)
	self.fangkaEnd = true
		
	--返还房卡
	local player = self:getPlayer(playerid)
	print("_______22_self.manager__",player)
	if player then 
		--在房间中
		local fangka = self:callGate(player, 'change_fangka', self.cost, reason)		
		if not fangka then --玩家不在线直接改数据库
			local sql = string.format("update usergame set room_ticket=room_ticket + %d where uid=%d",
				self.cost,playerid)		
			self.nodeMessage:sendService("mysql_service","execute", sql)		
		end
		for k,v in pairs(self.player_list) do 			
			--aa支付
			if k~=self.managerid and self.payer==2 then 
				--返卡
				if v.ready then 
					local fangka = self:callGate(v, 'change_fangka', self.cost, reason)		
					if fangka then 	
						local sql = string.format("update usergame set room_ticket=room_ticket + %d where uid=%d",
							self.cost,k)		
						self.nodeMessage:sendService("mysql_service","execute", sql)								
					end				
				end
			end	
		end

		self.nodeMessage:callGlobalService('tablestate','close_private',playerid, self.tableid)	
		self:voteTable()		
	else
		--重启服务器，会出现这种情况 只改数据库
		for k,v in pairs(self.player_list) do 			
			--aa支付
			if k~=self.managerid and self.payer==2 then 
				--返卡
				if v.ready then 
					local fangka = self:callGate(v, 'change_fangka', self.cost, reason)		
					if fangka then 	
						local sql = string.format("update usergame set room_ticket=room_ticket + %d where uid=%d",
							self.cost,k)		
						self.nodeMessage:sendService("mysql_service","execute", sql)								
					end				
				end
			end	
		end		

		self.nodeMessage:callGlobalService('tablestate','close_private',playerid, self.tableid)	
		self:voteTable()		
		log.debug("____房主开房好不在桌子里，",self.tableid,self.managerid)
	end

end
--激活关桌子
function Machine:closePrivate(playerid)
	print("_______playerid___",playerid,self.managerid)
	if playerid~=self.managerid then 
		return false
	end
	--没开局直接解散，开局后要投票
	if self.curJuShu > 0 then 
		self.tbCloseVote[playerid] = 1
		self:ntCloseVote()
		self.fsm2:fire("to_start")
		return false
	else
		self:deleteTable(self.managerid)
	end
	return true
end

--同意关桌子
function Machine:closeVote(playerid,args)
	print("________phz_close_vote_req___111",self.tbCloseVote)
	if next(self.tbCloseVote) then
		if self.tbCloseVote[playerid] then  
			return false
		end
	else
		self.sourceid = playerid
		self.fsm2:fire("to_start")
	end
	print("________phz_close_vote_req___2222")
	if args.agree then 
		self.tbCloseVote[playerid] = 1
	else
		self.tbCloseVote[playerid] = 2 --拒绝
	end
	local allClose = true
	for k,v in pairs(self.player_list) do 
		if not v.disconnect then 
			if not self.tbCloseVote[k] or self.tbCloseVote[k]==2 then 
				allClose = false
				break
			end
		end
	end
	print("________phz_close_vote_req__3333",allClose)
	if allClose then 
		--所有已关闭，解散桌子
		self.fsm2:fire("to_end")
	else
		--通知同意的人数增加了
		self:ntCloseVote()	
		if self.tbCloseVote[playerid]==2 then
			self.fsm2:fire("to_rest")
		end	
	end
	return true
end


---------------------------------------------------------
-- 状态
---------------------------------------------------------
--等侍
function Machine:onWait()
	-- log.debug("_______wait")
	local timehandler = nil
	local callback = function()
		if timehandler then
			return 
		end	
		-- self:removeDisconnect()
		self:removePlayer()
		--人数足2个才开始
		local num = 0
		local robotNum = 0
		for k,v in pairs(self.player_list) do 		
			if v.noReadyTime then
				v.noReadyTime = v.noReadyTime + self.statusTime.wait
				if v.noReadyTime > 10 then 
					--清除没准备的玩家
					v.noReadyTime = 0
					-- self:removeNoReady()
				end
			end				
			num = num + 1
			if v.robot then 
				robotNum = robotNum + 1
			end			
		end		
		-- self.waitTime = self.waitTime + self.statusTime.wait
		if self.curJuShu==0 then 
			self.waitTime = self.waitTime + self.statusTime.wait
			if self.waitTime>self.maxWaitTime then
				--没有开始10分钟后解散桌子
				log.debug("时间到没开始解散桌子",self.tableid,self.managerid)
				self.waitTime = 0
				self:deleteTable(self.managerid)
			end
		end
		if num < 3 then 
			return
		end		
		--
		-- local callback2 = function ( )		
			-- self.fsm:fire("to_rest")			
		-- end
		-- timehandler = self.timer:register(self.statusTime.wait,nil,callback2)
		--人数足3个才开始
		if self:getReadyNum() == 3 then
			self.fsm:fire("to_rest")
		end		
	end
	self:setTime(self.statusTime.wait,callback,true)
end

--休息
function Machine:onRest()
	-- log.debug("_______rest")
	-- self.operStartTime = os.time()
	--重置数据
	self:reset()

	self:removePlayer()

	--人数足3个才开始
	local num = self:getReadyNum()
	if num < 3 then 
		self.fsm:fire("to_wait")
		return false
	end	
	if self.close then --已关服
		return false
	end
	if self.fangkaEnd then 
		return 
	end	
	--通知客户端
	self:ntRest()	
	--洗牌
	self.rule:shuffle()
	self:makeCard()
	-- local function callback()
		self.fsm:fire("to_start")
	-- end	
	-- self:setTime(self.statusTime.rest,callback)
end

--开始
function Machine:onStart()
	log.debug("_______start")		
	self.operStartTime = os.time()	
	
	local player
	local cards
	local cardNum = 20	
	local cplayer
	self.paijuid = getRoundId(self.tableid)
	self.curJuShu = self.curJuShu + 1 --局数
	self.waitTime = 0
	self.bGameStart = true	
	if not self.startSeatid then --庄id
		self.startSeatid = 1 --math.random(1,3)
	end
	--准备好的玩家
	for seatid,playerid in pairs(self.seat_list) do 
		player = self.player_list[playerid]
		if player.ready then 
			player.playing = true
		end
		player.noReadyTime = 0
		
		if seatid == self.startSeatid then 
			--庄多一张牌
			cards = self.rule:getCard(cardNum+1)			
			-- table.insert(cards,tempCards[1])
			self.firstCard = cards[1]
		else
			cards = self.rule:getCard(cardNum)
		end		
		self.tbSeatCard[seatid] = cards

		cplayer = Player.new(self.rule)
		cplayer.seatid = seatid
		cplayer.playerid = playerid
		cplayer:initCards(table.copy(cards))
		self.tbPlayers[seatid] = cplayer

		local tb = {seatid=seatid,playerid=playerid,nick=player.nick,chip=player.chip,cards=cards}
		table.insert(self.tbCardRecord.game_start,tb)		
	end

	for seatid,playerid in pairs(self.seat_list) do 
		local data = {phz_nt_start={
	 		tableid = self.tableid,	
	 		ordinal = self.curJuShu, 
	 		cards = self.tbSeatCard[seatid],
	 		dealer = self.startSeatid,
	 		bright = self.firstCard,
	 		left_card = #self.rule:getLessCard(),
		}}		
		log.debug("_______start game_____data____",data)
		--通知到有座玩家拿牌
		self:sendMessage(playerid,data)
	end
	--通知无座玩家
	-- self:ntStart()
	self.tbCardRecord.game_config = {
		start_time=os.time(),		
		end_time=os.time(),
		card_num=4*10*2, 
		jushu=self.maxJuShu,
		cur_jushu=self.curJushu,
		payer=self.config.pay_type,
		roomid=self.tableNum,
		owner=self.managerid, 
		bottom_num=self.bottomNum,
		play_type=self.config.play_type,
		cap_num = self.config.cap_num, --封顶胡息
	}

	local callback = function()
		self.fsm:fire("to_first")
	end
	self:setTime(self.statusTime.start,callback)
end

--玩家操作
function Machine:onFirst()
	log.debug("____onFirst_________")
	--能否 提
	for k,v in pairs(self.tbPlayers) do 
		if v:check_ti_card() then
			--开始时提
			local tiRes = v:ti_card()
			print("开始时提牌结果",k,tiRes)
			for _,cards in pairs(tiRes) do 
				self:ntTi(k,cards)
			end
		end
		v:arrange_set() --坎牌整理
		-- self:ntHuxi(k)
		self:ntSomething(k)		
	end
	--天胡检查		
	local bHu = false	
	self.eventQueue:clear()
	bHu = self:checkHu(self.startSeatid,nil,1)	
	if bHu then 		
		self.fsm:fire("first_to_oper")
		return 	
	end		
			
	local callback = function()		
		self.curDealSeatid = self.startSeatid	
		self.fsm:fire("to_deal")		
	end
	self:setTime(self.statusTime.first,callback)
end

function Machine:onDeal()
	log.debug("____onDeal___",self.curDealSeatid)
	--清除之前的操作
	for k,v in pairs(self.tbPlayers) do
		v:set_this_turn_get()
		v:set_recent_play()
	end		
	local cplayer = self.tbPlayers[self.curDealSeatid]
	local set = cplayer:get_set()
	if not next(set) then 
		--没有可出的牌了
		self.curDealSeatid = self.curDealSeatid%#self.tbPlayers + 1	
		self.fsm:fire("deal_to_mopai")
		return
	end
	--出牌
	self:ntTurnDeal()
end

function Machine:onTiPaoWeiHu()	
	log.debug("___提偎跑后_胡____",self.curDealSeatid)
	local operId = self.curDealSeatid				
	local tb = {} --可做的操作			
	tb[operId] = {}
	tb[operId].hu = true
	self.tbPlayers[operId]:set_action_can_do(tb[operId])
	self.eventQueue:sort()	
	local callback = function ( ... )
		self:ntCanResponse(operId,tb[operId])	
	end		
	self:setTime(1,callback)
end


function Machine:onMopai()
	--摸牌
	log.debug("_______onMopai")		
	self.curDealCard = nil
	local tb = self.rule:getCard(1)
	self.curGetCard = tb[1]
	-- print("__11111111__rule.tbCard___",self.rule.tbCard)
	if not self.curGetCard then 
		--牌取完 和
		print("牌取完——和————",self.rule.tbCard)
		self.fsm:fire("to_settlement")
		return 
	end		
	local callback = function()
		self:ntTakeCard()
		--操作
		self.fsm:fire("to_oper")
	end
	self:setTime(1,callback)
end

--玩家操作
function Machine:onOper()
	log.debug("_______onOper")		
	
	--清除之前的操作
	for k,v in pairs(self.tbPlayers) do
		v:set_action_can_do({})
		v:set_this_turn_get()
		v:set_recent_play()
	end	
	local target = self.curDealSeatid
	if self.curGetCard then --摸的
		--有提,偎 自动转到出牌状态		
		print("等待玩家响应  座位为:",self.curDealSeatid)
	 	print("等待玩家响应  摸牌为:",self.curGetCard)	

		--判断玩家能否直接胡牌  能否 提 偎 等操作
		local c = self.curGetCard
		local plr = self.tbPlayers[target]
		plr:set_this_turn_get(c)
		-- for k,v in pairs(self.tbPlayers) do
		-- 	-- v:set_this_turn_get(c)
		-- 	v:set_recent_play()
		-- end		
		self.eventQueue:clear()
		if plr:check_ti_card(c) then
			local cards = plr:ti_card(c)
			print("提牌结果",cards,plr)
			--TODO通知前端提牌
			self:ntTi(target,cards)
			local function callback()
				if self:checkHu(target,nil,i) then 
					print("__提胡")				
					self.fsm:fire("to_tipaoweihu")
					return
				end
				local tbPao = plr:get_pao()
				local tbTi = plr:get_ti()
				if #tbPao + #tbTi>1 then --跑2次的不用出牌
					self.curDealSeatid = target%#self.tbPlayers + 1
					self.fsm:fire("to_mopai")
					return
				end				
				self.fsm:fire("to_deal")
			end
			self:setTime(1,callback)
			return 
		end
		if plr:check_wei_card(c) then
			local cards = plr:wei_card(c)
			print("偎牌结果",cards,plr)
			--TODO通知前端偎牌
			self:ntWei(target,cards)			
			local function callback()
				if self:checkHu(target,nil,i) then 
					print("__偎胡")	
					self.bWeiHu = true	
					self.fsm:fire("to_tipaoweihu")
					return
				end				
				self.fsm:fire("to_deal")
			end
			self:setTime(1,callback)			
			return 			
		end

		self.eventQueue:clear()
		local operId
		local tb = {} --可做的操作	
		for i=1,#self.tbPlayers do
			if not operId then
				operId = self.curDealSeatid
			else
				operId = operId % #self.tbPlayers + 1
			end
			tb[operId] = {}
			tb[operId].hu = self:checkHu(operId,c,i)
			self:checkPao(operId,c,i)
			tb[operId].peng = self:checkPeng(operId,c,i)
			if i <= 2 then
				tb[operId].chi,tb[operId].chi_info = self:checkChi(operId,c,i)
			end
			tb[operId].card = c			
			self.tbPlayers[operId]:set_action_can_do(tb[operId])
		end
		if self.eventQueue:size() == 0 then		
			local function callback()	
				self:enterConfirmPlay(self.curDealSeatid)
			end
			self:setTime(1,callback)
			return 
		end
		self.eventQueue:sort()

		local e = self.eventQueue:get_first_event()
		if e.type == e.PAO then
			--其他消息通知前端
			print("___________跑_______________")
			self:dealEvent(e)			
			return
		-- elseif e.type == e.HU then	
		-- 	print("___________胡__自摸_____________")		
		-- 	local function callback()
		-- 		self.fsm:fire("to_settlement")	
		-- 	end
		-- 	self:setTime(1,callback)						
		-- 	return
		else
			--通知
			operId = self.curDealSeatid
			local reponse
			for i=1,#self.tbPlayers do
				operId = operId%#self.tbPlayers + 1
				reponse = self.tbPlayers[operId]:get_action_can_do()
				if reponse and next(reponse) then 
					self:ntCanResponse(operId,reponse)
				end
			end
		end

	elseif self.curDealCard then 
		--玩家出牌
		--有跑没胡，自动跑
		print("等待玩家响应  座位为:",self.curDealSeatid)
	 	print("等待玩家响应  出牌为:",self.curDealCard)
		self.eventQueue:clear()
		local operId = self.curDealSeatid
		local tb = {}
		local c = self.curDealCard
		self.tbPlayers[operId]:set_recent_play(c)
		-- for k,v in pairs(self.tbPlayers) do
		-- 	v:set_this_turn_get()
		-- 	v:set_recent_play(c)
		-- end			
		for i=1,#self.tbPlayers - 1 do
			operId = operId%#self.tbPlayers + 1
			tb[operId] = {}
			print("__1111111111________",operId,c,i)
			tb[operId].hu = self:checkHu(operId,c,i)
			--pao可以不加入到t[tgt]中 这个到时候看情况而定
			--t[tgt].pao = 
			self:checkPao(operId,c,i,true)
			tb[operId].peng = self:checkPeng(operId,c,i)
			if i == 1 then
				tb[operId].chi,tb[operId].chi_info = self:checkChi(operId,c,i)
			end
			tb[operId].card = self.curDealCard
			self.tbPlayers[operId]:set_action_can_do(tb[operId])
		end

		if self.eventQueue:size() == 0 then
			--都没有 确认打牌 进入下一个阶段(玩家摸牌)			
			local function callback()	
				self:enterConfirmPlay(self.curDealSeatid)
			end
			self:setTime(1,callback)			
			return 
		end
		self.eventQueue:sort()
		local e = self.eventQueue:get_first_event()		
		if e.type == e.HU then
			--放炮
			local function callback()
				self.winnerSeatId = e.user
				self.fsm:fire("to_settlement")
			end
			self:setTime(1,callback)	
			return		
		elseif e.type == e.PAO then
			--其他消息通知前端
			print("____2_______跑_______________")
			self:dealEvent(e)
			return			
		else
			operId = self.curDealSeatid
			local reponse
			for i=1,#self.tbPlayers do
				operId = operId%#self.tbPlayers + 1
				reponse = self.tbPlayers[operId]:get_action_can_do()				
				if reponse and next(reponse) then 				
					self:ntCanResponse(operId,reponse)	
				end			
			end
		end
	else
		--天胡
		log.debug("___天胡____")
		local operId = self.startSeatid				
		local tb = {} --可做的操作			
		tb[operId] = {}
		tb[operId].hu = true
		self.tbPlayers[operId]:set_action_can_do(tb[operId])
		self.eventQueue:sort()	
		log.debug("_______tb___",tb)
		local callback = function ( ... )
			self:ntCanResponse(operId,tb[operId])	
		end		
		self:setTime(1,callback)
	end

end


--投票解散
function Machine:startVoteCallback()
	self.closeVoteTime = self.closeVoteTime - 1
	print("___self.closeVoteTime___",self.closeVoteTime)
	local canClose = true
	for k,v in pairs(self.player_list) do 
		if not self.tbCloseVote[k] or self.tbCloseVote[k]==2 then 
			canClose = false
		end
	end
	if canClose or self.closeVoteTime==0 then 
		self.fsm2:fire("to_end")
	end
end
function Machine:onStartVote()
	self.closeVoteTime = self.voteTime
	local callback = function ()		
		self:startVoteCallback()
	end
	self.handlerVoteTime = self.timer:register(1 , nil, callback,true)	
end
function Machine:onEndVote()	
	self.timer:unregister(self.handlerVoteTime)	
	self.handlerVoteTime = nil 	
	self.nodeMessage:callGlobalService('tablestate','close_private',playerid, self.tableid)			
	self:ntFangkaEnd()
end
function Machine:onRestVote()
	self.timer:unregister(self.handlerVoteTime)	
	self.handlerVoteTime = nil 
	self.tbCloseVote = {}
end


function Machine:executeFirstEvent()
	-- skynet.error("is_execute_first_event e_p_q",inspect(self.e_p_q))
	local evt = self.eventQueue:get_first_event()	
	if not evt then return end 
	if evt:is_confirm() or evt.type == evt.PAO then		
		return self:dealEvent(evt)
	end
end

--操作
function Machine:dealEvent(evt)
	local card_to_handle = self.curDealCard or self.curGetCard
	local turn = self.curDealSeatid
	for i=1,#self.tbPlayers do
		 self.tbPlayers[i]:set_action_can_do({})
	end
	local target = evt.user
	local plr = self.tbPlayers[target]
	local operType
	if evt.type == evt.HU then
		local result = evt.message
		print("__1111111__deal_event _____hu______")
		self.winnerSeatId = target
		self.fsm:fire("to_settlement")
		operType = self.operList.hu
	end

	if evt.type == evt.CHI then
		local tb = evt.message
		local t = plr:chi_card(card_to_handle,tb)
		plr:update_player_cards()
		self:ntChi(target,tb.cards,tb.comp)
		local function callback( ... )
			self.curDealSeatid = target
			self.fsm:fire("to_deal")
		end
		self:setTime(1,callback)
		operType = self.operList.chi
	end
	
	if evt.type == evt.PENG then
		local t = plr:peng_card(card_to_handle)
		plr:update_player_cards()
		self:ntPeng(target,t)
		local function callback( ... )
			self.curDealSeatid = target
			self.fsm:fire("to_deal")
		end
		self:setTime(1,callback)
		operType = self.operList.peng
	end

	if evt.type == evt.PAO then
		local t = plr:pao_card(card_to_handle)
		plr:update_player_cards()
		local c = card_to_handle
		local cards = {c,c,c,c}
		self:ntPao(target,cards)
		local function callback( ... )
			self.curDealSeatid = target
			self.eventQueue:clear()
			if self:checkHu(target,nil,target) then 
				log.debug("__跑胡")				
				self.fsm:fire("to_tipaoweihu")				
				return
			end							

			local tbPao = plr:get_pao()
			local tbTi = plr:get_ti()
			if #tbPao + #tbTi>1 then --跑2次的不用出牌
				self.curDealSeatid = target%#self.tbPlayers + 1
				self.fsm:fire("to_mopai")
			else
				self.fsm:fire("to_deal")
			end
		end
		self:setTime(1,callback)
		operType = self.operList.pao
	end
	for k,v in pairs(self.tbPlayers) do
		v:set_this_turn_get()
		v:set_recent_play()
	end	
	-- state 1正在玩2托管3准备4离线	
	-- seatid 座位id
	-- oper 操作1吃，2碰，3偎，4提，5跑，6胡，7出牌，8摸牌
	-- card 手牌
	local tbOperRecord = {
		seatid = target,
		oper = operType,
		card = card_to_handle,
		playerid = self.seat_list[target],		
	}
	if not self.tbCardRecord.game_oper[self.curRound] then 
		self.tbCardRecord.game_oper[self.curRound] = {}
	end	
	table.insert(self.tbCardRecord.game_oper[self.curRound],tbOperRecord)

	self.curRound = self.curRound + 1
end

--pro 优先级
function Machine:checkHu(target,c,pro)
	--胡牌算法
	local cplayer = self.tbPlayers[target]
	local bHu,huxi,tbMen = cplayer:check_hu_card(c) 		
	if bHu then
		local message = {user = target,tp = tp,set = set_t,gold_change = gold_change,recent_get = c,card_from = self.card_discard_from}
		local evt = Event.new()
		--这里传的tp需要后续确认各个玩家的优先级 tp表示优先级
		evt:ctor(target,evt.HU,pro,message)
		self.eventQueue:insert(evt)
		return true
	end
end

function Machine:checkPeng(target,c,pro)
	if self.tbPlayers[target]:check_peng_card(c) then
		local evt = Event.new()
		evt:ctor(target,evt.PENG,pro)
		self.eventQueue:insert(evt)
		return true
	end
end

function Machine:checkPao(target,c,pro,isOther)
	if self.tbPlayers[target]:check_pao_card(c,isOther) then
		local evt = Event.new()
		evt:ctor(target,evt.PAO,pro)
		self.eventQueue:insert(evt)
		return true
	end
end

function Machine:checkChi(target,c,pro)
	local set = self.tbPlayers[target]:get_set()	
	local falg,chi_data = self.rule:checkChi(set,c)
	if falg then
		log.debug("___checkChi___",set,c)
		local evt = Event.new()
		-- evt.message = chi_data
		evt:ctor(target,evt.CHI,pro)
		self.eventQueue:insert(evt)
		return true,chi_data
	end
end

function Machine:getWinnerResult(winnerSeatId)	
	local winnerRes = {}
	local huxi = 0
	local winHand = {}
	local tbMingTang = {}
	local bankerDeal = false 
	local ziMo = false
	local canHaiDi = false		
	local cplayer = self.tbPlayers[winnerSeatId]
	if not winnerSeatId then 
		return winnerRes
	end
	winHand = cplayer.tbMenzi
	huxi = cplayer.endHuxi

	if self.curDealSeatid == self.startSeatid then 
		bankerDeal = true --牌是庄出的
	end
	if winnerSeatId == self.curDealSeatid and self.curGetCard then 
		ziMo = true
	end
	if self.curGetCard then 
		--有海底胡的可能
		canHaiDi = true
	end
	tbMingTang = self.rule:checkMingTang(winHand,bankerDeal,ziMo,huxi,canHaiDi,self.curRound)
	local cardInfo = {
		win_hand = winHand,
		bottom_cards = self.rule:getLessCard(),
	}

	local totalHuxi = huxi --单局赢胡息
	local tbAchieves = {}
	local fanNum = 1
	for k,v in pairs(tbMingTang) do 
		fanNum = fanNum + v.fan
		huxi = huxi + v.huxi
		if v.fan > 0 then 
			table.insert(tbAchieves,v.name .. "+"..v.fan.."番")
		elseif v.huxi > 0 then
			table.insert(tbAchieves,v.name .. "+"..v.huxi.."胡息")
		end
	end
	totalHuxi = huxi * fanNum
	if totalHuxi > self.config.cap_num then 
		totalHuxi = self.config.cap_num
	end
	winnerRes = {
		huxi = huxi,
		total_huxi = totalHuxi,
		achieves = tbAchieves,
		hu_card = self.curGetCard or self.curDealCard,
		total_times = fanNum,
		card_info = cardInfo,
		sid = winnerSeatId,
	}
	self.tbWinNum[winnerSeatId] = self.tbWinNum[winnerSeatId] + 1

	return winnerRes
	
end

--结算
function Machine:onSettlement()
	log.debug("_______settlement")
	-- self.operStartTime = os.time()	
	local player 	
	local endPlayers = {}
	local endPlayer = {}

	log.debug("_______self.curDealCard__",self.curDealCard,self.curDealSeatid,self.winnerSeatId)
	local playerResult = {}
	local playerResults = {}
	
	local curTotalHuxi = 0
	local fengdingHuxi = 0
	local tbWinnerRes = {}
	local winnerRes = self:getWinnerResult(self.winnerSeatId)
	local action	
	local bFangPao = false	
	local curScore = 0 --分数计算
	local totalScore = 0	
	if self.winnerSeatId then 
		table.insert(tbWinnerRes,winnerRes)
		if self.curDealCard and self.curDealSeatid~=self.winnerSeatId  then
			bFangPao = true
		end
		for k,v in pairs(self.tbPlayers) do 
			if bFangPao and k~=self.winnerSeatId then 
				action = v:get_action_can_do()
				if action.hu then 
					winnerRes = self:getWinnerResult(k)
					table.insert(tbWinnerRes,winnerRes)
				end
			end
			v:set_action_can_do({})
		end
	end

	for seatid,playerid in pairs(self.seat_list) do 
		player = self:getPlayer(playerid) 
		playerResult = {}
		playerResult.sid = seatid
		playerResult.sex = player.sex
		playerResult.face_url = player.icon
		playerResult.name = player.nick
		playerResult.cur_score = player.chip 
		playerResult.change_score = 0	

		--放炮罚
		if bFangPao and seatid==self.curDealSeatid then 
			playerResult.change_score = 0
			for k,v in pairs(tbWinnerRes) do 
				player.chip = player.chip - v.total_huxi
				playerResult.change_score = playerResult.change_score-v.total_huxi				
			end			
			playerResult.cur_score = player.chip 
		else
			for k,v in pairs(tbWinnerRes) do 
				if seatid == v.sid then 
					player.chip = player.chip + v.total_huxi
					playerResult.cur_score = player.chip 
					playerResult.change_score = v.total_huxi
					if curTotalHuxi < player.chip then 
						curTotalHuxi = player.chip
					end
					if fengdingHuxi < v.total_huxi then 
						fengdingHuxi = v.total_huxi
					end
				end
			end			
		end			
		table.insert(playerResults,playerResult)

		--记录--------------------------------
		curScore = math.four_five(player.chip/10)*10--4舍5入
		endPlayer = {}
		endPlayer.seatid = seatid
		endPlayer.playerid = playerid
		endPlayer.chip = player.chip
		endPlayer.diamond = player.diamond	
		endPlayer.nick = player.nick or '无名字'	
		endPlayer.win_chip = playerResult.change_score
		endPlayer.be_fangpao = bFangPao
		if endPlayer.nick == "" then 
			endPlayer.nick = '无名字'
		end		
		endPlayer.win_score = 0
		endPlayer.winner_result = tbWinnerRes
		table.insert(endPlayers,endPlayer)

		totalScore = totalScore + curScore
		
	end

	--结算消息		
	local data = {phz_nt_end={
 		tableid = self.tableid,	
		cur_num = self.curJuShu,
		bottom_point = self.bottomNum,
		banker_sid = self.startSeatid,
	 	player_result = playerResults,	
	 	winner_result = tbWinnerRes,
	}}
	self.endData = data
	--通知客户端
	self:ntEnd(data)	

	--牌局记录
	-- for k,v in pairs(endPlayers) do 
	-- 	endPlayers[k].win_score = v.win_score*(#endPlayers) - totalScore
	-- end	
	self.tbCardRecord.game_end = endPlayers
	self:paijuRecord()

	if curTotalHuxi>=100 or fengdingHuxi>=self.config.cap_num then 
		self.fangkaEnd = true
		--总结算
		local callback = function()
			self:ntFangkaEnd()
		end			
		self:setTime(15, callback)		
		return 
	end
	--下局庄id
	local callback = function()
		self.fsm:fire("to_rest")
	end			
	if self.winnerSeatId then 
		self.startSeatid = self.winnerSeatId	
		for playerid,v in pairs(self.player_list) do 
			v.ready = false
		end
		-- self:setTime(self.statusTime.settlement, callback)
		return
	end
	--黄庄
	self:setTime(2, callback)


end




---------------------------------------------------------
-- public
---------------------------------------------------------

function Machine:getCharacter(player)
	local seatPlayer = {}
	seatPlayer.seatid = player.seatid
	seatPlayer.playerid = player.playerid
	seatPlayer.name = player.nick or '无名字'
	seatPlayer.chip = player.chip
	seatPlayer.diamond = player.diamond
	seatPlayer.icon = player.icon
	seatPlayer.viplevel = player.viplevel
	seatPlayer.level = player.level
	seatPlayer.sex = player.sex
	seatPlayer.score = player.chip
	-- seatPlayer.ready = player.ready	

	-- if not player.disconnect then 
	-- 	seatPlayer.online = true
	-- else
	-- 	seatPlayer.online = false
	-- end
	return seatPlayer
end

--取桌子状态
function Machine:getTableStatus(playerid)
	local seatPlayer
	local seatPlayers = {}
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	for sid,pid in pairs(self.seat_list) do
		if pid>0 then
			player = self.player_list[pid]
			-- log.debug("___player__",player)
			seatPlayer = self:getCharacter(player)
			seatPlayer.state = self:getPlayerState(player)
			table.insert(seatPlayers,seatPlayer)
		end
	end	

	local cplayer 
	local playerSets = {}
	local playerSet = {}
	local canResponse = {}
	local turnSeatid = 0 --出牌者id
	local leftCard = 0
	if self.bGameStart then 
		for i=1,#self.tbPlayers do 
			cplayer = self.tbPlayers[i]
			playerSet = {}
			playerSet.recent_play = cplayer:get_recent_play() --最近打出的那张牌
			playerSet.get_this_turn = cplayer:get_this_turn_get() --最近摸的那张牌
			playerSet.play_front = cplayer:get_play_front() --玩家打出的牌
			playerSet.left_card = #self.rule:getLessCard() --剩下可摸的牌
			playerSet.set = {}
			if i==seatid then 
				playerSet.set = {cards=cplayer:get_hand_set()} --手牌包括坎牌
				--吃碰偎提等牌的数据
				canResponse = cplayer:get_action_can_do()
			end
			playerSet.data = cplayer:get_deal_cards() --吃碰偎提等牌的数据
			playerSet.seatid = i			
			table.insert(playerSets,playerSet)
			seatPlayers[i].huxi = cplayer.frontHuxi	--显示的胡息		
		end
		-- if self:getState() == "deal" or self:getState() == "oper" then
		-- 	if not self.curGetCard then 
		-- 		turnSeatid = self.curDealSeatid
		-- 	end
		-- end
		if self:getState() == "deal" then 
			turnSeatid = self.curDealSeatid
		end
		leftCard = #self.rule:getLessCard()
		local function callback()
			self:ntTing(seatid)
		end
		self.timer:register(1,nil,callback)
	end	

	local status = {		
		chara_info = seatPlayers,
		room_info = self:getConfig(),
		verify_code = self.tableNum,
		player_set = playerSets,--{player_set},
		owner = self.managerid, --房主
		dealer = self.startSeatid, --庄家
		turn_seatid = turnSeatid , -- 出牌的玩家
		can_reponse = canResponse,--可以响应的动作
		left_card =leftCard, --牌库剩余牌
		game_started = self.bGameStart, --游戏是否开始
		state = 1, --游戏状态
		ordinal = self.curJuShu,
	}	
	
	if self:getState() == "settlement" then 
		local function callback()
			self:sendMessage(playerid,self.endData)
		end
		self:setTime(1,callback)
	end	

	log.debug("Table status################",self:getState(),status)	
	return status
end

--出牌
function Machine:playDeal(playerid,card)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local state = self:getState()
	print("playDeal___",seatid,card)
	if state ~= "deal" then 
		print("___________playDeal___error__")
		return false
	end
	if self.curDealSeatid ~= seatid then 
		return false 
	end
	if not card then 
		print("_____playDeal__card___ is nil_______",self.tbPlayers[seatid])
		return false 
	end
	local plr = self.tbPlayers[seatid]
	if not plr:is_valid_play(card) then
		print("someone_play!!!!!  not cards",self.curDealSeatid,seatid,plr:get_set())
		return
	end
	--self.timer_handler.cancel()
	plr:play_card(card)
	-- self.data.card_to_handle = c
	-- self.handler.play_card(target,c)


	--验证出的牌是否是在手牌中
	self.curDealCard = card
	self.curGetCard = nil
	self:ntDeal(seatid,card)
	local function callback()
		self.fsm:fire("to_oper")
	end
	self:setTime(1,callback)


		
	-- log.debug("___出牌错误______")
	return true
end

--确认出牌
function Machine:enterConfirmPlay(target)
	local card = self.curDealCard or self.curGetCard
	self.tbPlayers[target]:confirm_play(card)	
	self:ntConfirmCard(card)
	self.curDealSeatid = target%#self.tbPlayers + 1	
	local function callback()
		self.fsm:fire("to_mopai")	
		self.curRound = self.curRound + 1	
	end
	self:setTime(1,callback)

	return 
end

--过
function Machine:playNext(playerid)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local state = self:getState()
	print("__11111111_next_req_________playerid___",playerid,seatid)
	if state ~= "oper" and state ~= "tipaoweihu" then
		print("——————————cancel state error",state)
		return
	end
	local cplayer = self.tbPlayers[seatid]
	cplayer:set_action_can_do({})
	self.eventQueue:remove(seatid)
	if self.eventQueue:size() == 0 then
		if state == "tipaoweihu" then 
			if self.bWeiHu then 
				self.fsm:fire("to_deal")
			else
				local tbPao = cplayer:get_pao()
				local tbTi = cplayer:get_ti()
				if #tbPao + #tbTi>1 then --跑2次的不用出牌
					self.curDealSeatid = seatid%#self.tbPlayers + 1
					self.fsm:fire("to_mopai")
				else
					self.fsm:fire("to_deal")
				end			
			end
			return true
		end

		--没人可操作了，让下一个摸牌
		if not self.curDealSeatid then 
			--过天胡
			self.curRound = self.curRound + 1
			self.curDealSeatid = self.startSeatid
			local function callback()
				self.fsm:fire("to_deal")
			end
			self:setTime(1,callback)
			return true
		end
		self:enterConfirmPlay(self.curDealSeatid)
		return true
	end
	self:executeFirstEvent()

	return true
end


--胡
function Machine:playHu(playerid)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local state = self:getState()
	if state == "oper" or state == "tipaoweihu" then
		print("——————————playHu",seatid,playerid)
		self:hu(seatid)
		return true
	else		
	end	
	return false
end

function Machine:hu(target)	
	-- local plr = self.tbPlayers[target]
	if self.eventQueue:has(target,self.HU) then
		print("_____hu___",target)
		self.tbPlayers[target]:set_action_can_do({})
		self.eventQueue:confirm(target,self.HU)
		return self:executeFirstEvent()
	end
end


--吃
function Machine:playChi(playerid,args)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local state = self:getState()
	if state ~= "oper" then
		print("——————————cancel state error")
		return
	end
	local cards = args.cards
	local comp = args.comp	
	local card_to_handle = self.curDealCard or self.curGetCard
	local cplayer = self.tbPlayers[seatid]
	local target = seatid
	local t = {cards=cards,comp=comp}
	--需要检测是否可吃
	-- if self.eventQueue:has(target,self.CHI) and cplayer:is_valid_chi(card_to_handle,t) then
	if self.eventQueue:has(target,self.CHI) then
		self.tbPlayers[target]:set_action_can_do({})
		self.eventQueue:confirm(target,self.CHI,t)
		self:executeFirstEvent()
		return true
	end

	return false
end

--碰
function Machine:playPeng(playerid)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local state = self:getState()
	if state ~= "oper" then
		print("——————————cancel state error")
		return
	end
	local card_to_handle = self.curDealCard or self.curGetCard
	local player = self.tbPlayers[seatid]
	local target = seatid
	self.tbPlayers[target]:set_action_can_do({})
	print("__________111")
	if self.eventQueue:has(target,self.PENG) then
		print("__________222")
		self.eventQueue:confirm(target,self.PENG)
		print("__________333")
		self:executeFirstEvent()
		return true
	end
	print("__________444")
	
	return true
end

--准备
function Machine:playReady(playerid)
	local player = self:getPlayer(playerid)
	local seatid
	local state
	if self.fangkaEnd then 
		return false
	end
	if not player then 
		return false
	end
	seatid = player.seatid
	if not seatid or seatid == 0 then 
		return false
	end
	player.ready = true
	self:ntReady(playerid,seatid)

	--所有人都准备好
	if self:getReadyNum() == 3 then 
		if self:getState() == "settlement" then 
			local function callback()
				self.fsm:fire("to_rest")
			end
			self:setTime(1,callback)
		end
	end
	return true
end

--经纬度
function Machine:jingWei(playerid,args)
	local player = self:getPlayer(playerid)
	local seatid 
	local jd = args.jingdu or 0
	local wd = args.weidu or 0
	if not player then 
		return false
	end
	seatid = player.seatid
	self.tbJW[seatid] = {jd,wd}
	if self.bGameStart or table.size(self.tbJW)~=3 or table.size(self.seat_list)~=3 then 
		return true
	end
	local disDatas = {}
	local disData = {}	
	for k,v in pairs(self.player_list) do
		disData = {}
		disData.seatid = v.seatid
		disData.jingdu = self.tbJW[v.seatid][1]
		disData.weidu = self.tbJW[v.seatid][2]
		disData.uid = v.playerid
		disData.name = v.nick
		disData.ip = v.ip
		disData.icon = v.icon
		table.insert(disDatas,disData)
	end	
	local data = {
		phz_nt_distance = {
			data = disDatas,
		}
	}
	print("____jing wei du___",data)
	self:sendToAll(data)
	return true
end


--离开桌子
function Machine:leaveTable(playerid)
	local player = self:getPlayer(playerid)
	if self.curJuShu>0 or player.playing then 
		return false
	end
	log.debug('玩家离开牌桌>>>>>>>>>>>',playerid,self.managerid,self.tableid)
	if playerid == self.managerid then	
		--房主位置不清除
		player.ready = false	
		print("leaveTable房主离开桌子")		
		self:ntDisconnect(playerid)
		return true
	else
		--aa支付
		if self.curJuShu == 0 and self.payer==2 then 
			--返卡
			if player.ready then 
				local fangka = self:callGate(player, 'change_fangka', self.cost, reason)		
				if fangka then 				
				end				
			end
		end		
	end	
	self:sitUp(playerid)
	self.player_list[playerid] = nil
	self:updatePlayerNum()
	return true
end

--掉线处理
function Machine:disconnect(playerid)	
	local player = self.player_list[playerid]
	local seatid = player.seatid
	log.debug('玩家掉线>>>>>>>>>>>',playerid,self.managerid,self.tableid,player.playing,player.disconnect)
	if  playerid==self.managerid then 
		print("disconnect房主不能离开桌子")		
		self:ntDisconnect(playerid)		
		return false
	end
	--旁观者掉线马上踢出大厅,房主不能离开桌子
	if self.curJushu==0 and not player.playing and player.disconnect then 
		print("########在旁观玩家中直接踢走")	
		self:sendGate(player, 'update_tableid', 0)
		self:sitUp(playerid)
		self.player_list[playerid] = nil
		return true
	else
		self:ntDisconnect(playerid)			
	end	
	return false
end
-------------------------------------------------------------------------------
-- 推送消息
-------------------------------------------------------------------------------
function Machine:ntStart()
	log.debug("__________phz_start")
	local data = {phz_nt_start={
 		tableid = self.tableid,	
 		paijuid = self.paijuid,
 		seatid = self.startSeatid,
 		first_card = self.firstCard,
	}}
	log.debug(data)
	self:sendToNoSeat(data)
end


function Machine:ntRest()
	local data = {phz_nt_rest={
 		tableid = self.tableid,	
	}}
	self:sendToAll(data)	

end

function Machine:ntTurnDeal()
	local data = {phz_nt_turn_seat={
		seatid = self.curDealSeatid
	}}
	print("___ntTurnDeal___",data)
	self:sendToAll(data)
end

--推送玩家出牌
function Machine:ntDeal(seatid,card)
	local data = {phz_nt_play_card={
		seatid = seatid,
		card = card,
	}}
	self:sendToAll(data)

	self:ntSomething(seatid)
end

--确认出牌数据
function Machine:ntConfirmCard(card)
	local data = {phz_nt_confirm_card={
		seatid = self.curDealSeatid,
		cards = card
	}}
	self:sendToAll(data)
end


--推送玩家摸牌
function Machine:ntTakeCard()
	local data = {phz_nt_take_card={
		seatid = self.curDealSeatid,
		card = self.curGetCard,
		left_card = #self.rule:getLessCard(),
	}}
	self:sendToAll(data)
end

--玩家可操作
function Machine:ntCanResponse(seatid,reponse)
	local player = self:getPlayerBySeat(seatid)
	if reponse.chi or reponse.peng or reponse.hu then 
		local data = {phz_nt_can_reponse=reponse}
		print("___data_",data)
		self:sendMessage(player.playerid,data)		
	end
end

function Machine:ntTi(seatid,cards)
	local data = {phz_nt_ti={
		seatid = seatid,
		cards = cards,
	}}
	self:sendToAll(data)
	print("________phz_nt_ti__",data)
	self:ntSomething(seatid)
end

function Machine:ntPao(seatid,cards)
	local data = {phz_nt_pao={
		seatid = seatid,
		cards = cards,
	}}
	print("______pao__",data)
	self:sendToAll(data)

	self:ntSomething(seatid)
end

function Machine:ntWei(seatid,cards)
	local data = {phz_nt_wei={
		seatid = seatid,
		cards = cards,
	}}
	self:sendToAll(data)

	self:ntSomething(seatid)
end

function Machine:ntPeng(seatid,cards)
	local data = {phz_nt_peng={
		seatid = seatid,
		cards = cards,
	}}
	self:sendToAll(data)

	self:ntSomething(seatid)
end

function Machine:ntChi(seatid,cards,comp)
	local data = {phz_nt_chi={
		seatid = seatid,
		cards = cards,
		comp = comp,
	}}
	self:sendToAll(data)

	self:ntSomething(seatid)
end

function Machine:ntEnd(data)
		
	self:sendToAll(data)	
	log.debug("____ntEnd____",data)
end


function Machine:ntReady(playerid,seatid)	
	local seatPlayer = {seatid=seatid,state=self.playerState.ready}
	local data = {phz_nt_seat_change={
 		tableid = self.tableid,			 		
 		seat_player = seatPlayer, 	
 		playerid = playerid,	
 		seatid = seatid,
	}}	
	-- log.debug("__________data___",data)
	self:sendToAll(data)			
end

function Machine:ntSomething(seatid)
	self:ntHuxi(seatid)
	self:ntTing(seatid)
end

function Machine:ntHuxi(seatid)		
	local playerid = self.seat_list[seatid]
	local cplayer = self.tbPlayers[seatid]
	if not cplayer:checkHuxi() then 
		return 
	end
	local seatPlayer = {seatid=seatid,huxi=cplayer.frontHuxi}	
	local data = {phz_nt_seat_change={
 		tableid = self.tableid,			 		
 		seat_player = seatPlayer, 	
 		playerid = playerid,	
 		seatid = seatid,
	}}	
	log.debug("______ntHuxi__",seatid,data)
	self:sendToAll(data)			
end

function Machine:ntTing(seatid)
	print("_________ntTing____",seatid)
	local playerid = self.seat_list[seatid]
	local cplayer = self.tbPlayers[seatid]
	local res = cplayer:checkTing()
	local data = {}
	if res and next(res) then	 	
	 	local tb
		for k,v in pairs(res) do 
			tb={card=v}
			table.insert(data,tb)
		end	
		log.debug("__1111111_phz_nt_ting_",data)
	end	
	local sdata = {phz_nt_ting={
	 		data = data
		}}	
	
	self:sendMessage(playerid,sdata)		
end


--总结算通知
function Machine:ntFangkaEnd()
	self.fangkaEnd = true
	local endPlayers = {}
	local totalScore = 0
	local curScore = 0
	local player
	local maxChip = 0
	local bigWinnerId
	for seatid,playerid in pairs(self.seat_list) do 
		player = self:getPlayer(playerid)
		curScore = math.four_five(player.chip/10)*10--4舍5入
		endPlayers[seatid]={
			id = playerid,
			sex = player.sex,
			name = player.nick,
			face_url = player.icon,
			win_num = self.tbWinNum[seatid],
			cur_score = curScore,
			total_huxi = player.chip,
		}
		if player.chip > maxChip then 
			maxChip = player.chip
			bigWinnerId = playerid
		end
		totalScore = totalScore + curScore
	end

	local winScore = 0
	local str1 = 'qclandlord_winlog' 
	local sql1 
	local curJuShu = self.curJuShu
	if self:getState() ~= "settlement" then 
		curJuShu = curJuShu-1
	end
	--分数计算
	for k,v in pairs(endPlayers) do 		
		winScore = v.cur_score*(#endPlayers) - totalScore	
		endPlayers[k].cur_score = winScore
		sql1 = string.format("update qclandlord_winlog set winscore=%d where tid=%d and trdid=%d and uid=%d",					 
					 winScore,self.tableid, curJuShu,v.id)
		skynet.send("mysql_log", "lua", "execute", sql1)		
	end

	local data = {phz_nt_fanka_end={
 		tableid = self.tableid,	
 		owner_id = self.managerid,
 		player_infos = endPlayers,
 		big_winner_id = bigWinnerId,
	}}	
	self:sendToAll(data)	
	log.debug("____phz_nt_fanka_end____",data)

	--把所有人踢出房间后关闭服务
	self:voteTable()
	self.nodeMessage:callGlobalService('tablestate','close_private',playerid, self.tableid)		
end

function Machine:ntDisconnect(playerid)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	local seatPlayer = {seatid=seatid,state=self.playerState.disconnect}
	local data = {phz_nt_seat_change={
 		tableid = self.tableid,			 		
 		seat_player = seatPlayer, 	
 		playerid = playerid,	
 		seatid = seatid,
	}}	
	self:sendToOther(playerid,data)	
end

function Machine:ntOnconnect(playerid)
	local player = self:getPlayer(playerid)
	local seatid = player.seatid
	if not seatid or seatid==0 then 
		return 
	end
	local seatPlayer = {seatid=seatid,state=self:getPlayerState(player)}
	local data = {phz_nt_seat_change={
 		tableid = self.tableid,			 		
 		seat_player = seatPlayer, 	
 		playerid = playerid,	
 		seatid = seatid,
	}}	
	self:sendToOther(playerid,data)	
end

function Machine:voteTable()
	--把所有人踢出房间后关闭服务
	for k,v in pairs(self.player_list) do 	
		--设置玩家所在桌子id为0	
		self:sendGate(v, 'update_tableid', 0)
		-- self:sitUp(k)
		self.player_list[k] = nil
		self:updatePlayerNum()	
		local sql = string.format("delete from user_online where uid = %d;", k)
		skynet.send("mysql_service", "lua", "execute", sql)				
	end		
	self:exit()	
end

--投票解散
function Machine:ntCloseVote()	
	print("____ntCloseVote____",self.tbCloseVote)
	local tbPlayer={}
	local player={}
	for k,v in pairs(self.player_list) do 
		player = {}
		player.name = v.nick
		player.seatid = v.seatid
		player.playerid = v.playerid
		player.chip = v.chip
		player.diamond = v.diamond
		player.agree = (self.tbCloseVote[k] or 0)+1
		player.icon = v.icon
		table.insert(tbPlayer,player)
	end

	local data = {phz_nt_close_vote={
 		tableid = self.tableid,	
 		vote_player = tbPlayer,
 		time = self.closeVoteTime,
 		managerid = self.managerid,
 		sourceid = self.sourceid,
	}}	
	self:sendToAll(data)	
	log.debug("____phz_nt_close_vote____",data)

end
-------------------------------------------------------------------------------
-- 库存控制
-------------------------------------------------------------------------------
--计算机器人输赢
function Machine:robotSettlement()

end

--检查库存
function Machine:checkStock()
	return false
end

-------------------------------------------------------------------------------
-- 牌局记录
-------------------------------------------------------------------------------
function Machine:paijuRecord()
	local tableName = 'qclandlord_tablelog'
	local str = tableName .." (tid,trdid,svid,tlcnt,tllog,tltime,game,gameid,gametype,room_owner,room_flag)"
	local jsonStr = json.encode(self.tbCardRecord)
	local tlcnt = 3 --玩家数
	local game = 3
	local sql = string.format("insert into %s value(%d,%d,%d,%d,'%s',%d,%d,%d,%d,%d,%s)",
		str,self.tableid,self.curJuShu,self.gameid,tlcnt,jsonStr,os.time(),game,self.gameid,self.roomid,self.managerid,self.room_flag)
	local res = skynet.call("mysql_log", "lua", "execute", sql)
	if not res then 
		return 
	end
	local tlid = res.insert_id
	if not tlid then 
		return
	end
	local time = os.time()
	self.tbCardRecord.game_config.end_time = time
	for k, v in pairs(self.tbCardRecord.game_end) do
		local wlfold = 0 --下注
		local player = self.player_list[v.playerid]
		local wlleft = v.chip
		local wlwin = v.win_chip 
		local winScore = v.win_score
		local wlflag = 2 --平局
		if wlwin > 0 then
			wlflag = 1
		else
			wlflag = 0 
		end
		local svid = self.gameid
		local str1 = 'qclandlord_winlog' .. 
					" (tlid,uid,pfid,usid,tid, room_id,svid,trdid,wlfold,wlleft, wlwin,wlflag,wltime,game,gameid, gametype,winscore)"
		local sql1 = string.format("insert into %s values(%d,%d,%d,%d,%d, %d,%d,%d,%d,%d, %d,%d,%d,%d,%d, %d,%d);",
					 str1, tlid, v.playerid, player.pfid or 0, player.usid or 0,
					 self.tableid, self.roomid, svid,self.curJuShu, wlfold, wlleft, 
					 wlwin, wlflag, time, player.game or 0,self.gameid, self.roomid,winScore)
		local res = skynet.call("mysql_log", "lua", "execute", sql1)
		print("-------------------------------->res sql1",res, sql1)
	end
end




-----------------------------------------------------------------------------------
----------------------------------
-- 数据操作
----------------------------------


--桌子相关配置
function Machine:getConfig()
	return {
		play_type = self.config.play_type,
		game_num = self.config.play_count,
		cap_num = self.config.cap_num,
		cost_type = self.config.cost_type,
		game_id = self.gameid,
		clubid =  self.config.clubid,
		owner =  self.config.owner,
		verify_code = self.config.verify_code,
		close_time = self.maxWaitTime-self.waitTime,
		table_flag = self.room_flag,
	}
end

--做牌
function Machine:makeCard()

	local sql = "select * from make_cards where id = "..self.gameid
	local tb = skynet.call("mysql_log", "lua", "execute", sql)
	if not tb then
		return
	end	
	tb = tb[1]	
	if not tb then
		return 
	end
	local isOpen = tb.isOpen
	local tableid = tb.tableid
	local cards1 = tb.player1
	local cards2 = tb.player2
	local cards3 = tb.player3
	if isOpen == 0 then 
		return 
	end
	if not tableid or tableid ~= self.tableid then 
		-- return
	end
	cards1 = json.decode(cards1)
	cards2 = json.decode(cards2)
	cards3 = json.decode(cards3)
	self.rule:setCard(cards1,cards2,cards3)
end


----------------------------------------------------------------------------------------------
---------开始游戏
---------------------------------------------------------------------------------------------- 
function Machine:start()
	self.fsm:set("settlement")
	self.fsm:fire("to_rest")
end

return Machine